home *** CD-ROM | disk | FTP | other *** search
/ PC/CD Gamer UK 120 / CD Gamer Issue 120 (March 2003) (Disc 2).ISO / mods / Q2_Codered / codeRED1_0.exe / Data1.cab / g_items.c1 < prev    next >
Encoding:
Text File  |  2002-11-23  |  47.9 KB  |  2,235 lines

  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. #include "g_local.h"
  21.  
  22.  
  23. qboolean    Pickup_Weapon (edict_t *ent, edict_t *other);
  24. void        Use_Weapon (edict_t *ent, gitem_t *inv);
  25. void        Drop_Weapon (edict_t *ent, gitem_t *inv);
  26.  
  27. void Weapon_Blaster (edict_t *ent);
  28. void Weapon_Shotgun (edict_t *ent);
  29. void Weapon_SuperShotgun (edict_t *ent);
  30. void Weapon_Machinegun (edict_t *ent);
  31. void Weapon_Chaingun (edict_t *ent);
  32. void Weapon_HyperBlaster (edict_t *ent);
  33. void Weapon_RocketLauncher (edict_t *ent);
  34. void Weapon_Grenade (edict_t *ent);
  35. void Weapon_GrenadeLauncher (edict_t *ent);
  36. void Weapon_Railgun (edict_t *ent);
  37. void Weapon_BFG (edict_t *ent);
  38.  
  39. gitem_armor_t jacketarmor_info    = { 25,  50, .30, .00, ARMOR_JACKET};
  40. gitem_armor_t combatarmor_info    = { 50, 100, .60, .30, ARMOR_COMBAT};
  41. gitem_armor_t bodyarmor_info    = {100, 200, .80, .60, ARMOR_BODY};
  42.  
  43. static int    jacket_armor_index;
  44. static int    combat_armor_index;
  45. static int    body_armor_index;
  46. static int    power_screen_index;
  47. static int    power_shield_index;
  48.  
  49. #define HEALTH_IGNORE_MAX    1
  50. #define HEALTH_TIMED        2
  51.  
  52. void Use_Quad (edict_t *ent, gitem_t *item);
  53. static int    quad_drop_timeout_hack;
  54.  
  55. //======================================================================
  56.  
  57. /*
  58. ===============
  59. GetItemByIndex
  60. ===============
  61. */
  62. gitem_t    *GetItemByIndex (int index)
  63. {
  64.     if (index == 0 || index >= game.num_items)
  65.         return NULL;
  66.  
  67.     return &itemlist[index];
  68. }
  69.  
  70.  
  71. /*
  72. ===============
  73. FindItemByClassname
  74.  
  75. ===============
  76. */
  77. gitem_t    *FindItemByClassname (char *classname)
  78. {
  79.     int        i;
  80.     gitem_t    *it;
  81.  
  82.     it = itemlist;
  83.     for (i=0 ; i<game.num_items ; i++, it++)
  84.     {
  85.         if (!it->classname)
  86.             continue;
  87.         if (!Q_stricmp(it->classname, classname))
  88.             return it;
  89.     }
  90.  
  91.     return NULL;
  92. }
  93.  
  94. /*
  95. ===============
  96. FindItem
  97.  
  98. ===============
  99. */
  100. gitem_t    *FindItem (char *pickup_name)
  101. {
  102.     int        i;
  103.     gitem_t    *it;
  104.  
  105.     it = itemlist;
  106.     for (i=0 ; i<game.num_items ; i++, it++)
  107.     {
  108.         if (!it->pickup_name)
  109.             continue;
  110.         if (!Q_stricmp(it->pickup_name, pickup_name))
  111.             return it;
  112.     }
  113.  
  114.     return NULL;
  115. }
  116.  
  117. //======================================================================
  118.  
  119. void DoRespawn (edict_t *ent)
  120. {
  121.     if (ent->team)
  122.     {
  123.         edict_t    *master;
  124.         int    count;
  125.         int choice;
  126.  
  127.         master = ent->teammaster;
  128.  
  129.         for (count = 0, ent = master; ent; ent = ent->chain, count++)
  130.             ;
  131.  
  132.         choice = rand() % count;
  133.  
  134.         for (count = 0, ent = master; count < choice; ent = ent->chain, count++)
  135.             ;
  136.     }
  137.  
  138.     ent->svflags &= ~SVF_NOCLIENT;
  139.     ent->solid = SOLID_TRIGGER;
  140.     gi.linkentity (ent);
  141.  
  142.     // send an effect
  143.     ent->s.event = EV_ITEM_RESPAWN;
  144. }
  145.  
  146. void SetRespawn (edict_t *ent, float delay)
  147. {
  148.     ent->flags |= FL_RESPAWN;
  149.     ent->svflags |= SVF_NOCLIENT;
  150.     ent->solid = SOLID_NOT;
  151.     ent->nextthink = level.time + delay;
  152.     ent->think = DoRespawn;
  153.     gi.linkentity (ent);
  154. }
  155.  
  156.  
  157. //======================================================================
  158.  
  159. qboolean Pickup_Powerup (edict_t *ent, edict_t *other)
  160. {
  161.     int        quantity;
  162.  
  163.     quantity = other->client->pers.inventory[ITEM_INDEX(ent->item)];
  164.     if ((skill->value == 1 && quantity >= 2) || (skill->value >= 2 && quantity >= 1))
  165.         return false;
  166.  
  167.     if ((coop->value) && (ent->item->flags & IT_STAY_COOP) && (quantity > 0))
  168.         return false;
  169.  
  170.     other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
  171.  
  172.     if (deathmatch->value)
  173.     {
  174.         if (!(ent->spawnflags & DROPPED_ITEM) )
  175.             SetRespawn (ent, ent->item->quantity);
  176.         if (((int)dmflags->value & DF_INSTANT_ITEMS) || ((ent->item->use == Use_Quad) && (ent->spawnflags & DROPPED_PLAYER_ITEM)))
  177.         {
  178.             if ((ent->item->use == Use_Quad) && (ent->spawnflags & DROPPED_PLAYER_ITEM))
  179.                 quad_drop_timeout_hack = (ent->nextthink - level.time) / FRAMETIME;
  180.             ent->item->use (other, ent->item);
  181.         }
  182.     }
  183.  
  184.     return true;
  185. }
  186.  
  187. void Drop_General (edict_t *ent, gitem_t *item)
  188. {
  189.     Drop_Item (ent, item);
  190.     ent->client->pers.inventory[ITEM_INDEX(item)]--;
  191.     ValidateSelectedItem (ent);
  192. }
  193.  
  194.  
  195. //======================================================================
  196.  
  197. qboolean Pickup_Adrenaline (edict_t *ent, edict_t *other)
  198. {
  199.     if (!deathmatch->value)
  200.         other->max_health += 1;
  201.  
  202.     if (other->health < other->max_health)
  203.         other->health = other->max_health;
  204.  
  205.     if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
  206.         SetRespawn (ent, ent->item->quantity);
  207.  
  208.     return true;
  209. }
  210.  
  211. qboolean Pickup_AncientHead (edict_t *ent, edict_t *other)
  212. {
  213.     other->max_health += 2;
  214.  
  215.     if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
  216.         SetRespawn (ent, ent->item->quantity);
  217.  
  218.     return true;
  219. }
  220.  
  221. qboolean Pickup_Bandolier (edict_t *ent, edict_t *other)
  222. {
  223.     gitem_t    *item;
  224.     int        index;
  225.  
  226.     if (other->client->pers.max_bullets < 250)
  227.         other->client->pers.max_bullets = 250;
  228.     if (other->client->pers.max_shells < 150)
  229.         other->client->pers.max_shells = 150;
  230.     if (other->client->pers.max_cells < 250)
  231.         other->client->pers.max_cells = 250;
  232.     if (other->client->pers.max_slugs < 75)
  233.         other->client->pers.max_slugs = 75;
  234.  
  235.     item = FindItem("Bullets");
  236.     if (item)
  237.     {
  238.         index = ITEM_INDEX(item);
  239.         other->client->pers.inventory[index] += item->quantity;
  240.         if (other->client->pers.inventory[index] > other->client->pers.max_bullets)
  241.             other->client->pers.inventory[index] = other->client->pers.max_bullets;
  242.     }
  243.  
  244.     item = FindItem("Alien Smart Grenade");
  245.     if (item)
  246.     {
  247.         index = ITEM_INDEX(item);
  248.         other->client->pers.inventory[index] += item->quantity;
  249.         if (other->client->pers.inventory[index] > other->client->pers.max_shells)
  250.             other->client->pers.inventory[index] = other->client->pers.max_shells;
  251.     }
  252.  
  253.     if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
  254.         SetRespawn (ent, ent->item->quantity);
  255.  
  256.     return true;
  257. }
  258.  
  259. qboolean Pickup_Pack (edict_t *ent, edict_t *other)
  260. {
  261.     gitem_t    *item;
  262.     int        index;
  263.  
  264.     if (other->client->pers.max_bullets < 300)
  265.         other->client->pers.max_bullets = 300;
  266.     if (other->client->pers.max_shells < 200)
  267.         other->client->pers.max_shells = 200;
  268.     if (other->client->pers.max_rockets < 100)
  269.         other->client->pers.max_rockets = 100;
  270.     if (other->client->pers.max_grenades < 100)
  271.         other->client->pers.max_grenades = 100;
  272.     if (other->client->pers.max_cells < 300)
  273.         other->client->pers.max_cells = 300;
  274.     if (other->client->pers.max_slugs < 100)
  275.         other->client->pers.max_slugs = 100;
  276.  
  277.     item = FindItem("Bullets");
  278.     if (item)
  279.     {
  280.         index = ITEM_INDEX(item);
  281.         other->client->pers.inventory[index] += item->quantity;
  282.         if (other->client->pers.inventory[index] > other->client->pers.max_bullets)
  283.             other->client->pers.inventory[index] = other->client->pers.max_bullets;
  284.     }
  285.  
  286.     item = FindItem("Alien Smart Grenade");
  287.     if (item)
  288.     {
  289.         index = ITEM_INDEX(item);
  290.         other->client->pers.inventory[index] += item->quantity;
  291.         if (other->client->pers.inventory[index] > other->client->pers.max_shells)
  292.             other->client->pers.inventory[index] = other->client->pers.max_shells;
  293.     }
  294.  
  295.     item = FindItem("Cells");
  296.     if (item)
  297.     {
  298.         index = ITEM_INDEX(item);
  299.         other->client->pers.inventory[index] += item->quantity;
  300.         if (other->client->pers.inventory[index] > other->client->pers.max_cells)
  301.             other->client->pers.inventory[index] = other->client->pers.max_cells;
  302.     }
  303.  
  304.     item = FindItem("Napalm");
  305.     if (item)
  306.     {
  307.         index = ITEM_INDEX(item);
  308.         other->client->pers.inventory[index] += item->quantity;
  309.         if (other->client->pers.inventory[index] > other->client->pers.max_grenades)
  310.             other->client->pers.inventory[index] = other->client->pers.max_grenades;
  311.     }
  312.  
  313.     item = FindItem("Rockets");
  314.     if (item)
  315.     {
  316.         index = ITEM_INDEX(item);
  317.         other->client->pers.inventory[index] += item->quantity;
  318.         if (other->client->pers.inventory[index] > other->client->pers.max_rockets)
  319.             other->client->pers.inventory[index] = other->client->pers.max_rockets;
  320.     }
  321.  
  322.     item = FindItem("Slugs");
  323.     if (item)
  324.     {
  325.         index = ITEM_INDEX(item);
  326.         other->client->pers.inventory[index] += item->quantity;
  327.         if (other->client->pers.inventory[index] > other->client->pers.max_slugs)
  328.             other->client->pers.inventory[index] = other->client->pers.max_slugs;
  329.     }
  330.  
  331.     if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
  332.         SetRespawn (ent, ent->item->quantity);
  333.  
  334.     return true;
  335. }
  336.  
  337. //======================================================================
  338.  
  339. void Use_Quad (edict_t *ent, gitem_t *item)
  340. {
  341.     int        timeout;
  342.  
  343.     ent->client->pers.inventory[ITEM_INDEX(item)]--;
  344.     ValidateSelectedItem (ent);
  345.  
  346.     if (quad_drop_timeout_hack)
  347.     {
  348.         timeout = quad_drop_timeout_hack;
  349.         quad_drop_timeout_hack = 0;
  350.     }
  351.     else
  352.     {
  353.         timeout = 300;
  354.     }
  355.  
  356.     if (ent->client->quad_framenum > level.framenum)
  357.         ent->client->quad_framenum += timeout;
  358.     else
  359.         ent->client->quad_framenum = level.framenum + timeout;
  360.  
  361.     gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0);
  362. }
  363.  
  364. //======================================================================
  365.  
  366. void Use_Breather (edict_t *ent, gitem_t *item)
  367. {
  368.     ent->client->pers.inventory[ITEM_INDEX(item)]--;
  369.     ValidateSelectedItem (ent);
  370.  
  371.     if (ent->client->breather_framenum > level.framenum)
  372.         ent->client->breather_framenum += 300;
  373.     else
  374.         ent->client->breather_framenum = level.framenum + 300;
  375.  
  376. //    gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0);
  377. }
  378.  
  379. //======================================================================
  380.  
  381. void Use_Envirosuit (edict_t *ent, gitem_t *item)
  382. {
  383.     ent->client->pers.inventory[ITEM_INDEX(item)]--;
  384.     ValidateSelectedItem (ent);
  385.  
  386.     if (ent->client->enviro_framenum > level.framenum)
  387.         ent->client->enviro_framenum += 300;
  388.     else
  389.         ent->client->enviro_framenum = level.framenum + 300;
  390.  
  391. //    gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0);
  392. }
  393.  
  394. //======================================================================
  395.  
  396. void    Use_Invulnerability (edict_t *ent, gitem_t *item)
  397. {
  398.     ent->client->pers.inventory[ITEM_INDEX(item)]--;
  399.     ValidateSelectedItem (ent);
  400.  
  401.     if (ent->client->invincible_framenum > level.framenum)
  402.         ent->client->invincible_framenum += 300;
  403.     else
  404.         ent->client->invincible_framenum = level.framenum + 300;
  405.  
  406.     gi.sound(ent, CHAN_ITEM, gi.soundindex("items/protect.wav"), 1, ATTN_NORM, 0);
  407. }
  408.  
  409. //======================================================================
  410.  
  411. void    Use_Silencer (edict_t *ent, gitem_t *item)
  412. {
  413.     ent->client->pers.inventory[ITEM_INDEX(item)]--;
  414.     ValidateSelectedItem (ent);
  415.     ent->client->silencer_shots += 30;
  416.  
  417. //    gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0);
  418. }
  419.  
  420. //======================================================================
  421.  
  422. qboolean Pickup_Key (edict_t *ent, edict_t *other)
  423. {
  424.     if (coop->value)
  425.     {
  426.         if (strcmp(ent->classname, "key_power_cube") == 0)
  427.         {
  428.             if (other->client->pers.power_cubes & ((ent->spawnflags & 0x0000ff00)>> 8))
  429.                 return false;
  430.             other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
  431.             other->client->pers.power_cubes |= ((ent->spawnflags & 0x0000ff00) >> 8);
  432.         }
  433.         else
  434.         {
  435.             if (other->client->pers.inventory[ITEM_INDEX(ent->item)])
  436.                 return false;
  437.             other->client->pers.inventory[ITEM_INDEX(ent->item)] = 1;
  438.         }
  439.         return true;
  440.     }
  441.     other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
  442.     return true;
  443. }
  444.  
  445. //======================================================================
  446.  
  447. qboolean Add_Ammo (edict_t *ent, gitem_t *item, int count)
  448. {
  449.     int            index;
  450.     int            max;
  451.  
  452.     if (!ent->client)
  453.         return false;
  454.  
  455.     if (item->tag == AMMO_BULLETS)
  456.         max = ent->client->pers.max_bullets;
  457.     else if (item->tag == AMMO_SHELLS)
  458.         max = ent->client->pers.max_shells;
  459.     else if (item->tag == AMMO_ROCKETS)
  460.         max = ent->client->pers.max_rockets;
  461.     else if (item->tag == AMMO_GRENADES)
  462.         max = ent->client->pers.max_grenades;
  463.     else if (item->tag == AMMO_CELLS)
  464.         max = ent->client->pers.max_cells;
  465.     else if (item->tag == AMMO_SLUGS)
  466.         max = ent->client->pers.max_slugs;
  467.     else
  468.         return false;
  469.  
  470.     index = ITEM_INDEX(item);
  471.  
  472.     if (ent->client->pers.inventory[index] == max)
  473.         return false;
  474.  
  475.     ent->client->pers.inventory[index] += count;
  476.  
  477.     if (ent->client->pers.inventory[index] > max)
  478.         ent->client->pers.inventory[index] = max;
  479.  
  480.     return true;
  481. }
  482.  
  483. qboolean Pickup_Ammo (edict_t *ent, edict_t *other)
  484. {
  485.     int            oldcount;
  486.     int            count;
  487.     qboolean    weapon;
  488.  
  489.     weapon = (ent->item->flags & IT_WEAPON);
  490.     if ( (weapon) && ( (int)dmflags->value & DF_INFINITE_AMMO ) )
  491.         count = 1000;
  492.     else if (ent->count)
  493.         count = ent->count;
  494.     else
  495.         count = ent->item->quantity;
  496.  
  497.     oldcount = other->client->pers.inventory[ITEM_INDEX(ent->item)];
  498.  
  499.     if (!Add_Ammo (other, ent->item, count))
  500.         return false;
  501.  
  502.     if (weapon && !oldcount)
  503.     {
  504.         if (other->client->pers.weapon != ent->item && ( !deathmatch->value || other->client->pers.weapon == FindItem("blaster") ) )
  505.             other->client->newweapon = ent->item;
  506.     }
  507.  
  508.     if (!(ent->spawnflags & (DROPPED_ITEM | DROPPED_PLAYER_ITEM)) && (deathmatch->value))
  509.         SetRespawn (ent, 30);
  510.     return true;
  511. }
  512.  
  513. void Drop_Ammo (edict_t *ent, gitem_t *item)
  514. {
  515.     edict_t    *dropped;
  516.     int        index;
  517.  
  518.     index = ITEM_INDEX(item);
  519.     dropped = Drop_Item (ent, item);
  520.     if (ent->client->pers.inventory[index] >= item->quantity)
  521.         dropped->count = item->quantity;
  522.     else
  523.         dropped->count = ent->client->pers.inventory[index];
  524.  
  525.     if (ent->client->pers.weapon && 
  526.         ent->client->pers.weapon->tag == AMMO_GRENADES &&
  527.         item->tag == AMMO_GRENADES &&
  528.         ent->client->pers.inventory[index] - dropped->count <= 0) {
  529.         gi.cprintf (ent, PRINT_HIGH, "Can't drop current weapon\n");
  530.         G_FreeEdict(dropped);
  531.         return;
  532.     }
  533.  
  534.     ent->client->pers.inventory[index] -= dropped->count;
  535.     ValidateSelectedItem (ent);
  536. }
  537.  
  538.  
  539. //======================================================================
  540.  
  541. void MegaHealth_think (edict_t *self)
  542. {
  543.     if (self->owner->health > self->owner->max_health)
  544.     {
  545.         self->nextthink = level.time + 1;
  546.         self->owner->health -= 1;
  547.         return;
  548.     }
  549.  
  550.     if (!(self->spawnflags & DROPPED_ITEM) && (deathmatch->value))
  551.         SetRespawn (self, 20);
  552.     else
  553.         G_FreeEdict (self);
  554. }
  555. void Healthbox_think (edict_t *self)
  556. {
  557.     
  558.     self->nextthink = level.time + 7;
  559.     self->s.effects = 0;
  560.     self->s.renderfx = RF_GLOW;
  561.     return;
  562. }
  563. qboolean Pickup_Health (edict_t *ent, edict_t *other)
  564. {
  565.     if (!(ent->style & HEALTH_IGNORE_MAX))
  566.         if (other->health >= other->max_health)
  567.         {
  568.             gi.sound(ent, CHAN_AUTO, gi.soundindex("misc/reject.wav"), 1, ATTN_NORM, 0);
  569.             ent->s.effects |= EF_COLOR_SHELL;
  570.             ent->s.renderfx |= RF_SHELL_GREEN;
  571.             ent->think = Healthbox_think;
  572.             ent->nextthink = level.time + 7;
  573.             return false;
  574.         }
  575.  
  576.     other->health += ent->count;
  577.  
  578.     if (!(ent->style & HEALTH_IGNORE_MAX))
  579.     {
  580.         if (other->health > other->max_health)
  581.             other->health = other->max_health;
  582.     }
  583.  
  584.     if (ent->style & HEALTH_TIMED)
  585.     {
  586.         ent->think = MegaHealth_think;
  587.         ent->nextthink = level.time + 5;
  588.         ent->owner = other;
  589.         ent->flags |= FL_RESPAWN;
  590.         ent->svflags |= SVF_NOCLIENT;
  591.         ent->solid = SOLID_NOT;
  592.     }
  593.     else
  594.     {
  595.         if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
  596.             SetRespawn (ent, 30);
  597.     }
  598.  
  599.     return true;
  600. }
  601.  
  602. //======================================================================
  603.  
  604. int ArmorIndex (edict_t *ent)
  605. {
  606.     if (!ent->client)
  607.         return 0;
  608.  
  609.     if (ent->client->pers.inventory[jacket_armor_index] > 0)
  610.         return jacket_armor_index;
  611.  
  612.     if (ent->client->pers.inventory[combat_armor_index] > 0)
  613.         return combat_armor_index;
  614.  
  615.     if (ent->client->pers.inventory[body_armor_index] > 0)
  616.         return body_armor_index;
  617.  
  618.     return 0;
  619. }
  620.  
  621. qboolean Pickup_Armor (edict_t *ent, edict_t *other)
  622. {
  623.     int                old_armor_index;
  624.     gitem_armor_t    *oldinfo;
  625.     gitem_armor_t    *newinfo;
  626.     int                newcount;
  627.     float            salvage;
  628.     int                salvagecount;
  629.  
  630.     // get info on new armor
  631.     newinfo = (gitem_armor_t *)ent->item->info;
  632.  
  633.     old_armor_index = ArmorIndex (other);
  634.  
  635.     // handle armor shards specially
  636.     if (ent->item->tag == ARMOR_SHARD)
  637.     {
  638.         if (!old_armor_index)
  639.             other->client->pers.inventory[jacket_armor_index] = 2;
  640.         else
  641.             other->client->pers.inventory[old_armor_index] += 2;
  642.     }
  643.  
  644.     // if player has no armor, just use it
  645.     else if (!old_armor_index)
  646.     {
  647.         other->client->pers.inventory[ITEM_INDEX(ent->item)] = newinfo->base_count;
  648.     }
  649.  
  650.     // use the better armor
  651.     else
  652.     {
  653.         // get info on old armor
  654.         if (old_armor_index == jacket_armor_index)
  655.             oldinfo = &jacketarmor_info;
  656.         else if (old_armor_index == combat_armor_index)
  657.             oldinfo = &combatarmor_info;
  658.         else // (old_armor_index == body_armor_index)
  659.             oldinfo = &bodyarmor_info;
  660.  
  661.         if (newinfo->normal_protection > oldinfo->normal_protection)
  662.         {
  663.             // calc new armor values
  664.             salvage = oldinfo->normal_protection / newinfo->normal_protection;
  665.             salvagecount = salvage * other->client->pers.inventory[old_armor_index];
  666.             newcount = newinfo->base_count + salvagecount;
  667.             if (newcount > newinfo->max_count)
  668.                 newcount = newinfo->max_count;
  669.  
  670.             // zero count of old armor so it goes away
  671.             other->client->pers.inventory[old_armor_index] = 0;
  672.  
  673.             // change armor to new item with computed value
  674.             other->client->pers.inventory[ITEM_INDEX(ent->item)] = newcount;
  675.         }
  676.         else
  677.         {
  678.             // calc new armor values
  679.             salvage = newinfo->normal_protection / oldinfo->normal_protection;
  680.             salvagecount = salvage * newinfo->base_count;
  681.             newcount = other->client->pers.inventory[old_armor_index] + salvagecount;
  682.             if (newcount > oldinfo->max_count)
  683.                 newcount = oldinfo->max_count;
  684.  
  685.             // if we're already maxed out then we don't need the new armor
  686.             if (other->client->pers.inventory[old_armor_index] >= newcount)
  687.                 return false;
  688.  
  689.             // update current armor value
  690.             other->client->pers.inventory[old_armor_index] = newcount;
  691.         }
  692.     }
  693.  
  694.     if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
  695.         SetRespawn (ent, 20);
  696.  
  697.     return true;
  698. }
  699.  
  700. //======================================================================
  701.  
  702. int PowerArmorType (edict_t *ent)
  703. {
  704.     if (!ent->client)
  705.         return POWER_ARMOR_NONE;
  706.  
  707.     if (!(ent->flags & FL_POWER_ARMOR))
  708.         return POWER_ARMOR_NONE;
  709.  
  710.     if (ent->client->pers.inventory[power_shield_index] > 0)
  711.         return POWER_ARMOR_SHIELD;
  712.  
  713.     if (ent->client->pers.inventory[power_screen_index] > 0)
  714.         return POWER_ARMOR_SCREEN;
  715.  
  716.     return POWER_ARMOR_NONE;
  717. }
  718.  
  719. void Use_PowerArmor (edict_t *ent, gitem_t *item)
  720. {
  721.     int        index;
  722.  
  723.     if (ent->flags & FL_POWER_ARMOR)
  724.     {
  725.         ent->flags &= ~FL_POWER_ARMOR;
  726.         gi.sound(ent, CHAN_AUTO, gi.soundindex("misc/power2.wav"), 1, ATTN_NORM, 0);
  727.     }
  728.     else
  729.     {
  730.         index = ITEM_INDEX(FindItem("cells"));
  731.         if (!ent->client->pers.inventory[index])
  732.         {
  733.             gi.cprintf (ent, PRINT_HIGH, "No cells for power armor.\n");
  734.             return;
  735.         }
  736.         ent->flags |= FL_POWER_ARMOR;
  737.         gi.sound(ent, CHAN_AUTO, gi.soundindex("misc/power1.wav"), 1, ATTN_NORM, 0);
  738.     }
  739. }
  740.  
  741. qboolean Pickup_PowerArmor (edict_t *ent, edict_t *other)
  742. {
  743.     int        quantity;
  744.  
  745.     quantity = other->client->pers.inventory[ITEM_INDEX(ent->item)];
  746.  
  747.     other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
  748.  
  749.     if (deathmatch->value)
  750.     {
  751.         if (!(ent->spawnflags & DROPPED_ITEM) )
  752.             SetRespawn (ent, ent->item->quantity);
  753.         // auto-use for DM only if we didn't already have one
  754.         if (!quantity)
  755.             ent->item->use (other, ent->item);
  756.     }
  757.  
  758.     return true;
  759. }
  760.  
  761. void Drop_PowerArmor (edict_t *ent, gitem_t *item)
  762. {
  763.     if ((ent->flags & FL_POWER_ARMOR) && (ent->client->pers.inventory[ITEM_INDEX(item)] == 1))
  764.         Use_PowerArmor (ent, item);
  765.     Drop_General (ent, item);
  766. }
  767.  
  768. //======================================================================
  769.  
  770. /*
  771. ===============
  772. Touch_Item
  773. ===============
  774. */
  775. void Touch_Item (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
  776. {
  777.     qboolean    taken;
  778.  
  779.     if (!other->client)
  780.         return;
  781.     if (other->health < 1)
  782.         return;        // dead people can't pickup
  783.     if (!ent->item->pickup)
  784.         return;        // not a grabbable item?
  785.  
  786.     taken = ent->item->pickup(ent, other);
  787.  
  788.     if (taken)
  789.     {
  790.         // flash the screen
  791.         other->client->bonus_alpha = 0.25;    
  792.  
  793.         // show icon and name on status bar
  794.         other->client->ps.stats[STAT_PICKUP_ICON] = gi.imageindex(ent->item->icon);
  795.         other->client->ps.stats[STAT_PICKUP_STRING] = CS_ITEMS+ITEM_INDEX(ent->item);
  796.         other->client->pickup_msg_time = level.time + 3.0;
  797.  
  798.         // change selected item
  799.         if (ent->item->use)
  800.             other->client->pers.selected_item = other->client->ps.stats[STAT_SELECTED_ITEM] = ITEM_INDEX(ent->item);
  801.  
  802.         if (ent->item->pickup == Pickup_Health)
  803.         {
  804.             if (ent->count == 2)
  805.                 gi.sound(other, CHAN_ITEM, gi.soundindex("items/s_health.wav"), 1, ATTN_NORM, 0);
  806.             else if (ent->count == 10)
  807.                 gi.sound(other, CHAN_ITEM, gi.soundindex("items/n_health.wav"), 1, ATTN_NORM, 0);
  808.             else if (ent->count == 25)
  809.                 gi.sound(other, CHAN_ITEM, gi.soundindex("items/l_health.wav"), 1, ATTN_NORM, 0);
  810.             else // (ent->count == 100)
  811.                 gi.sound(other, CHAN_ITEM, gi.soundindex("items/m_health.wav"), 1, ATTN_NORM, 0);
  812.         }
  813.         else if (ent->item->pickup_sound)
  814.         {
  815.             gi.sound(other, CHAN_ITEM, gi.soundindex(ent->item->pickup_sound), 1, ATTN_NORM, 0);
  816.         }
  817.     }
  818.  
  819.     if (!(ent->spawnflags & ITEM_TARGETS_USED))
  820.     {
  821.         G_UseTargets (ent, other);
  822.         ent->spawnflags |= ITEM_TARGETS_USED;
  823.     }
  824.  
  825.     if (!taken)
  826.         return;
  827.  
  828.     if (!((coop->value) &&  (ent->item->flags & IT_STAY_COOP)) || (ent->spawnflags & (DROPPED_ITEM | DROPPED_PLAYER_ITEM)))
  829.     {
  830.         if (ent->flags & FL_RESPAWN)
  831.             ent->flags &= ~FL_RESPAWN;
  832.         else
  833.             G_FreeEdict (ent);
  834.     }
  835. }
  836.  
  837. //======================================================================
  838.  
  839. static void drop_temp_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
  840. {
  841.     if (other == ent->owner)
  842.         return;
  843.  
  844.     Touch_Item (ent, other, plane, surf);
  845. }
  846.  
  847. static void drop_make_touchable (edict_t *ent)
  848. {
  849.     ent->touch = Touch_Item;
  850.     if (deathmatch->value)
  851.     {
  852.         ent->nextthink = level.time + 29;
  853.         ent->think = G_FreeEdict;
  854.     }
  855. }
  856.  
  857. edict_t *Drop_Item (edict_t *ent, gitem_t *item)
  858. {
  859.     edict_t    *dropped;
  860.     vec3_t    forward, right;
  861.     vec3_t    offset;
  862.  
  863.     dropped = G_Spawn();
  864.  
  865.     dropped->classname = item->classname;
  866.     dropped->item = item;
  867.     dropped->spawnflags = DROPPED_ITEM;
  868.     dropped->s.effects = item->world_model_flags;
  869.     dropped->s.renderfx = RF_GLOW;
  870.     VectorSet (dropped->mins, -15, -15, -15);
  871.     VectorSet (dropped->maxs, 15, 15, 15);
  872.     gi.setmodel (dropped, dropped->item->world_model);
  873.     dropped->solid = SOLID_TRIGGER;
  874.     dropped->movetype = MOVETYPE_TOSS;  
  875.     dropped->touch = drop_temp_touch;
  876.     dropped->owner = ent;
  877.  
  878.     if (ent->client)
  879.     {
  880.         trace_t    trace;
  881.  
  882.         AngleVectors (ent->client->v_angle, forward, right, NULL);
  883.         VectorSet(offset, 24, 0, -16);
  884.         G_ProjectSource (ent->s.origin, offset, forward, right, dropped->s.origin);
  885.         trace = gi.trace (ent->s.origin, dropped->mins, dropped->maxs,
  886.             dropped->s.origin, ent, CONTENTS_SOLID);
  887.         VectorCopy (trace.endpos, dropped->s.origin);
  888.     }
  889.     else
  890.     {
  891.         AngleVectors (ent->s.angles, forward, right, NULL);
  892.         VectorCopy (ent->s.origin, dropped->s.origin);
  893.     }
  894.  
  895.     VectorScale (forward, 100, dropped->velocity);
  896.     dropped->velocity[2] = 300;
  897.  
  898.     dropped->think = drop_make_touchable;
  899.     dropped->nextthink = level.time + 1;
  900.  
  901.     gi.linkentity (dropped);
  902.  
  903.     return dropped;
  904. }
  905.  
  906. void Use_Item (edict_t *ent, edict_t *other, edict_t *activator)
  907. {
  908.     ent->svflags &= ~SVF_NOCLIENT;
  909.     ent->use = NULL;
  910.  
  911.     if (ent->spawnflags & ITEM_NO_TOUCH)
  912.     {
  913.         ent->solid = SOLID_BBOX;
  914.         ent->touch = NULL;
  915.     }
  916.     else
  917.     {
  918.         ent->solid = SOLID_TRIGGER;
  919.         ent->touch = Touch_Item;
  920.     }
  921.  
  922.     gi.linkentity (ent);
  923. }
  924.  
  925. //======================================================================
  926.  
  927. /*
  928. ================
  929. droptofloor
  930. ================
  931. */
  932. void droptofloor (edict_t *ent)
  933. {
  934.     trace_t        tr;
  935.     vec3_t        dest;
  936.     float        *v;
  937.  
  938.     v = tv(-15,-15,-15);
  939.     VectorCopy (v, ent->mins);
  940.     v = tv(15,15,15);
  941.     VectorCopy (v, ent->maxs);
  942.  
  943.     if (ent->model)
  944.         gi.setmodel (ent, ent->model);
  945.     else
  946.         gi.setmodel (ent, ent->item->world_model);
  947.     ent->solid = SOLID_TRIGGER;
  948.     ent->movetype = MOVETYPE_TOSS;  
  949.     ent->touch = Touch_Item;
  950.  
  951.     v = tv(0,0,-128);
  952.     VectorAdd (ent->s.origin, v, dest);
  953.  
  954.     tr = gi.trace (ent->s.origin, ent->mins, ent->maxs, dest, ent, MASK_SOLID);
  955.     if (tr.startsolid)
  956.     {
  957.         gi.dprintf ("droptofloor: %s startsolid at %s\n", ent->classname, vtos(ent->s.origin));
  958.         G_FreeEdict (ent);
  959.         return;
  960.     }
  961.  
  962.     VectorCopy (tr.endpos, ent->s.origin);
  963.  
  964.     if (ent->team)
  965.     {
  966.         ent->flags &= ~FL_TEAMSLAVE;
  967.         ent->chain = ent->teamchain;
  968.         ent->teamchain = NULL;
  969.  
  970.         ent->svflags |= SVF_NOCLIENT;
  971.         ent->solid = SOLID_NOT;
  972.         if (ent == ent->teammaster)
  973.         {
  974.             ent->nextthink = level.time + FRAMETIME;
  975.             ent->think = DoRespawn;
  976.         }
  977.     }
  978.  
  979.     if (ent->spawnflags & ITEM_NO_TOUCH)
  980.     {
  981.         ent->solid = SOLID_BBOX;
  982.         ent->touch = NULL;
  983.         ent->s.effects &= ~EF_ROTATE;
  984.         ent->s.renderfx &= ~RF_GLOW;
  985.     }
  986.  
  987.     if (ent->spawnflags & ITEM_TRIGGER_SPAWN)
  988.     {
  989.         ent->svflags |= SVF_NOCLIENT;
  990.         ent->solid = SOLID_NOT;
  991.         ent->use = Use_Item;
  992.     }
  993.  
  994.     gi.linkentity (ent);
  995. }
  996.  
  997.  
  998. /*
  999. ===============
  1000. PrecacheItem
  1001.  
  1002. Precaches all data needed for a given item.
  1003. This will be called for each item spawned in a level,
  1004. and for each item in each client's inventory.
  1005. ===============
  1006. */
  1007. void PrecacheItem (gitem_t *it)
  1008. {
  1009.     char    *s, *start;
  1010.     char    data[MAX_QPATH];
  1011.     int        len;
  1012.     gitem_t    *ammo;
  1013.  
  1014.     if (!it)
  1015.         return;
  1016.  
  1017.     if (it->pickup_sound)
  1018.         gi.soundindex (it->pickup_sound);
  1019.     if (it->world_model)
  1020.         gi.modelindex (it->world_model);
  1021.     if (it->view_model)
  1022.         gi.modelindex (it->view_model);
  1023.     if (it->icon)
  1024.         gi.imageindex (it->icon);
  1025.  
  1026.     // parse everything for its ammo
  1027.     if (it->ammo && it->ammo[0])
  1028.     {
  1029.         ammo = FindItem (it->ammo);
  1030.         if (ammo != it)
  1031.             PrecacheItem (ammo);
  1032.     }
  1033.  
  1034.     // parse the space seperated precache string for other items
  1035.     s = it->precaches;
  1036.     if (!s || !s[0])
  1037.         return;
  1038.  
  1039.     while (*s)
  1040.     {
  1041.         start = s;
  1042.         while (*s && *s != ' ')
  1043.             s++;
  1044.  
  1045.         len = s-start;
  1046.         if (len >= MAX_QPATH || len < 5)
  1047.             gi.error ("PrecacheItem: %s has bad precache string", it->classname);
  1048.         memcpy (data, start, len);
  1049.         data[len] = 0;
  1050.         if (*s)
  1051.             s++;
  1052.  
  1053.         // determine type based on extension
  1054.         if (!strcmp(data+len-3, "md2"))
  1055.             gi.modelindex (data);
  1056.         else if (!strcmp(data+len-3, "sp2"))
  1057.             gi.modelindex (data);
  1058.         else if (!strcmp(data+len-3, "wav"))
  1059.             gi.soundindex (data);
  1060.         if (!strcmp(data+len-3, "pcx"))
  1061.             gi.imageindex (data);
  1062.     }
  1063. }
  1064.  
  1065. /*
  1066. ============
  1067. SpawnItem
  1068.  
  1069. Sets the clipping size and plants the object on the floor.
  1070.  
  1071. Items can't be immediately dropped to floor, because they might
  1072. be on an entity that hasn't spawned yet.
  1073. ============
  1074. */
  1075. void SpawnItem (edict_t *ent, gitem_t *item)
  1076. {
  1077.     PrecacheItem (item);
  1078.  
  1079.     if (ent->spawnflags)
  1080.     {
  1081.         if (strcmp(ent->classname, "key_power_cube") != 0)
  1082.         {
  1083.             ent->spawnflags = 0;
  1084.             gi.dprintf("%s at %s has invalid spawnflags set\n", ent->classname, vtos(ent->s.origin));
  1085.         }
  1086.     }
  1087.  
  1088.     // some items will be prevented in deathmatch
  1089.     if (deathmatch->value)
  1090.     {
  1091.         if ( (int)dmflags->value & DF_NO_ARMOR )
  1092.         {
  1093.             if (item->pickup == Pickup_Armor || item->pickup == Pickup_PowerArmor)
  1094.             {
  1095.                 G_FreeEdict (ent);
  1096.                 return;
  1097.             }
  1098.         }
  1099.         if ( (int)dmflags->value & DF_NO_ITEMS )
  1100.         {
  1101.             if (item->pickup == Pickup_Powerup)
  1102.             {
  1103.                 G_FreeEdict (ent);
  1104.                 return;
  1105.             }
  1106.         }
  1107.         if ( (int)dmflags->value & DF_NO_HEALTH )
  1108.         {
  1109.             if (item->pickup == Pickup_Health || item->pickup == Pickup_Adrenaline || item->pickup == Pickup_AncientHead)
  1110.             {
  1111.                 G_FreeEdict (ent);
  1112.                 return;
  1113.             }
  1114.         }
  1115.         if ( (int)dmflags->value & DF_INFINITE_AMMO )
  1116.         {
  1117.             if ( (item->flags == IT_AMMO) || (strcmp(ent->classname, "weapon_bfg") == 0) )
  1118.             {
  1119.                 G_FreeEdict (ent);
  1120.                 return;
  1121.             }
  1122.         }
  1123.     }
  1124.  
  1125.     if (coop->value && (strcmp(ent->classname, "key_power_cube") == 0))
  1126.     {
  1127.         ent->spawnflags |= (1 << (8 + level.power_cubes));
  1128.         level.power_cubes++;
  1129.     }
  1130.  
  1131.     // don't let them drop items that stay in a coop game
  1132.     if ((coop->value) && (item->flags & IT_STAY_COOP))
  1133.     {
  1134.         item->drop = NULL;
  1135.     }
  1136.  
  1137.     ent->item = item;
  1138.     ent->nextthink = level.time + 2 * FRAMETIME;    // items start after other solids
  1139.     ent->think = droptofloor;
  1140.     ent->s.effects = item->world_model_flags;
  1141.     ent->s.renderfx = RF_GLOW;
  1142.     if (ent->model)
  1143.         gi.modelindex (ent->model);
  1144. }
  1145.  
  1146. //======================================================================
  1147.  
  1148. gitem_t    itemlist[] = 
  1149. {
  1150.     {
  1151.         NULL
  1152.     },    // leave index 0 alone
  1153.  
  1154.     //
  1155.     // ARMOR
  1156.     //
  1157.  
  1158. /*QUAKED item_armor_body (.3 .3 1) (-16 -16 -16) (16 16 16)
  1159. */
  1160.     {
  1161.         "item_armor_body", 
  1162.         Pickup_Armor,
  1163.         NULL,
  1164.         NULL,
  1165.         NULL,
  1166.         "misc/ar1_pkup.wav",
  1167.         "models/items/armor/body/tris.md2", EF_ROTATE,
  1168.         NULL,
  1169. /* icon */        "i_bodyarmor",
  1170. /* pickup */    "Body Armor",
  1171. /* width */        3,
  1172.         0,
  1173.         NULL,
  1174.         IT_ARMOR,
  1175.         0,
  1176.         &bodyarmor_info,
  1177.         ARMOR_BODY,
  1178. /* precache */ ""
  1179.     },
  1180.  
  1181. /*QUAKED item_armor_combat (.3 .3 1) (-16 -16 -16) (16 16 16)
  1182. */
  1183.     {
  1184.         "item_armor_combat", 
  1185.         Pickup_Armor,
  1186.         NULL,
  1187.         NULL,
  1188.         NULL,
  1189.         "misc/ar1_pkup.wav",
  1190.         "models/items/armor/combat/tris.md2", EF_ROTATE,
  1191.         NULL,
  1192. /* icon */        "i_combatarmor",
  1193. /* pickup */    "Combat Armor",
  1194. /* width */        3,
  1195.         0,
  1196.         NULL,
  1197.         IT_ARMOR,
  1198.         0,
  1199.         &combatarmor_info,
  1200.         ARMOR_COMBAT,
  1201. /* precache */ ""
  1202.     },
  1203.  
  1204. /*QUAKED item_armor_jacket (.3 .3 1) (-16 -16 -16) (16 16 16)
  1205. */
  1206.     {
  1207.         "item_armor_jacket", 
  1208.         Pickup_Armor,
  1209.         NULL,
  1210.         NULL,
  1211.         NULL,
  1212.         "misc/ar1_pkup.wav",
  1213.         "models/items/armor/jacket/tris.md2", EF_ROTATE,
  1214.         NULL,
  1215. /* icon */        "i_jacketarmor",
  1216. /* pickup */    "Jacket Armor",
  1217. /* width */        3,
  1218.         0,
  1219.         NULL,
  1220.         IT_ARMOR,
  1221.         0,
  1222.         &jacketarmor_info,
  1223.         ARMOR_JACKET,
  1224. /* precache */ ""
  1225.     },
  1226.  
  1227. /*QUAKED item_armor_shard (.3 .3 1) (-16 -16 -16) (16 16 16)
  1228. */
  1229.     {
  1230.         "item_armor_shard", 
  1231.         Pickup_Armor,
  1232.         NULL,
  1233.         NULL,
  1234.         NULL,
  1235.         "misc/ar2_pkup.wav",
  1236.         "models/items/armor/shard/tris.md2", EF_ROTATE,
  1237.         NULL,
  1238. /* icon */        "i_jacketarmor",
  1239. /* pickup */    "Armor Shard",
  1240. /* width */        3,
  1241.         0,
  1242.         NULL,
  1243.         IT_ARMOR,
  1244.         0,
  1245.         NULL,
  1246.         ARMOR_SHARD,
  1247. /* precache */ ""
  1248.     },
  1249.  
  1250.  
  1251. /*QUAKED item_power_screen (.3 .3 1) (-16 -16 -16) (16 16 16)
  1252. */
  1253.     {
  1254.         "item_power_screen", 
  1255.         Pickup_PowerArmor,
  1256.         Use_PowerArmor,
  1257.         Drop_PowerArmor,
  1258.         NULL,
  1259.         "misc/ar3_pkup.wav",
  1260.         "models/items/armor/screen/tris.md2", EF_ROTATE,
  1261.         NULL,
  1262. /* icon */        "i_powerscreen",
  1263. /* pickup */    "Power Screen",
  1264. /* width */        0,
  1265.         60,
  1266.         NULL,
  1267.         IT_ARMOR,
  1268.         0,
  1269.         NULL,
  1270.         0,
  1271. /* precache */ ""
  1272.     },
  1273.  
  1274. /*QUAKED item_power_shield (.3 .3 1) (-16 -16 -16) (16 16 16)
  1275. */
  1276.     {
  1277.         "item_power_shield",
  1278.         Pickup_PowerArmor,
  1279.         Use_PowerArmor,
  1280.         Drop_PowerArmor,
  1281.         NULL,
  1282.         "misc/ar3_pkup.wav",
  1283.         "models/items/armor/shield/tris.md2", EF_ROTATE,
  1284.         NULL,
  1285. /* icon */        "i_powershield",
  1286. /* pickup */    "Power Shield",
  1287. /* width */        0,
  1288.         60,
  1289.         NULL,
  1290.         IT_ARMOR,
  1291.         0,
  1292.         NULL,
  1293.         0,
  1294. /* precache */ "misc/power2.wav misc/power1.wav"
  1295.     },
  1296.  
  1297.  
  1298.     //
  1299.     // WEAPONS 
  1300.     //
  1301.  
  1302. /* weapon_blaster (.3 .3 1) (-16 -16 -16) (16 16 16)
  1303. always owned, never in the world
  1304. */
  1305.     {
  1306.         "weapon_blaster", 
  1307.         NULL,
  1308.         Use_Weapon,
  1309.         NULL,
  1310.         Weapon_Blaster,
  1311.         "misc/w_pkup.wav",
  1312.         NULL, 0,
  1313.         "models/weapons/v_blast/tris.md2",
  1314. /* icon */        "w_blaster",
  1315. /* pickup */    "Blaster",
  1316.         0,
  1317.         0,
  1318.         NULL,
  1319.         IT_WEAPON|IT_STAY_COOP,
  1320.         WEAP_BLASTER,
  1321.         NULL,
  1322.         0,
  1323. /* precache */ "weapons/blastf1a.wav misc/lasfly.wav"
  1324.     },
  1325.  
  1326. /*QUAKED weapon_shotgun (.3 .3 1) (-16 -16 -16) (16 16 16)
  1327. */
  1328.     {
  1329.         "weapon_shotgun", 
  1330.         Pickup_Weapon,
  1331.         Use_Weapon,
  1332.         Drop_Weapon,
  1333.         Weapon_Shotgun,
  1334.         "misc/w_pkup.wav",
  1335.         "models/weapons/g_shotg/tris.md2", EF_ROTATE,
  1336.         "models/weapons/v_shotg/tris.md2",
  1337. /* icon */        "w_shotgun",
  1338. /* pickup */    "Alien Smartgun",
  1339.         0,
  1340.         1,
  1341.         "Alien Smart Grenade",
  1342.         IT_WEAPON|IT_STAY_COOP,
  1343.         WEAP_SHOTGUN,
  1344.         NULL,
  1345.         0,
  1346. /* precache */ "weapons/shotgf1b.wav weapons/shotgr1b.wav"
  1347.     },
  1348.  
  1349. /*QUAKED weapon_supershotgun (.3 .3 1) (-16 -16 -16) (16 16 16)
  1350. */
  1351.     {
  1352.         "weapon_supershotgun", 
  1353.         Pickup_Weapon,
  1354.         Use_Weapon,
  1355.         Drop_Weapon,
  1356.         Weapon_SuperShotgun,
  1357.         "misc/w_pkup.wav",
  1358.         "models/weapons/g_shotg2/tris.md2", EF_ROTATE,
  1359.         "models/weapons/v_shotg2/tris.md2",
  1360. /* icon */        "w_sshotgun",
  1361. /* pickup */    "Pulse Rifle",
  1362.         0,
  1363.         2,
  1364.         "Bullets",
  1365.         IT_WEAPON|IT_STAY_COOP,
  1366.         WEAP_SUPERSHOTGUN,
  1367.         NULL,
  1368.         0,
  1369. /* precache */ "weapons/sshotf1b.wav"
  1370.     },
  1371.  
  1372. /*QUAKED weapon_machinegun (.3 .3 1) (-16 -16 -16) (16 16 16)
  1373. */
  1374.     {
  1375.         "weapon_machinegun", 
  1376.         Pickup_Weapon,
  1377.         Use_Weapon,
  1378.         Drop_Weapon,
  1379.         Weapon_Machinegun,
  1380.         "misc/w_pkup.wav",
  1381.         "models/weapons/g_machn/tris.md2", EF_ROTATE,
  1382.         "models/weapons/v_machn/tris.md2",
  1383. /* icon */        "w_machinegun",
  1384. /* pickup */    "Machinegun",
  1385.         0,
  1386.         1,
  1387.         "Bullets",
  1388.         IT_WEAPON|IT_STAY_COOP,
  1389.         WEAP_MACHINEGUN,
  1390.         NULL,
  1391.         0,
  1392. /* precache */ "weapons/machgf1b.wav weapons/machgf2b.wav weapons/machgf3b.wav weapons/machgf4b.wav weapons/machgf5b.wav"
  1393.     },
  1394.  
  1395. /*QUAKED weapon_chaingun (.3 .3 1) (-16 -16 -16) (16 16 16)
  1396. */
  1397.     {
  1398.         "weapon_chaingun", 
  1399.         Pickup_Weapon,
  1400.         Use_Weapon,
  1401.         Drop_Weapon,
  1402.         Weapon_Chaingun,
  1403.         "misc/w_pkup.wav",
  1404.         "models/weapons/g_chain/tris.md2", EF_ROTATE,
  1405.         "models/weapons/v_chain/tris.md2",
  1406. /* icon */        "w_chaingun",
  1407. /* pickup */    "Flame Thrower",
  1408.         0,
  1409.         1,
  1410.         "Napalm",
  1411.         IT_WEAPON|IT_STAY_COOP,
  1412.         WEAP_CHAINGUN,
  1413.         NULL,
  1414.         0,
  1415. /* precache */ "weapons/chngnu1a.wav weapons/chngnl1a.wav weapons/machgf3b.wav` weapons/chngnd1a.wav"
  1416.     },
  1417.  
  1418. /*QUAKED weapon_grenadelauncher (.3 .3 1) (-16 -16 -16) (16 16 16)
  1419. */
  1420.     {
  1421.         "weapon_grenadelauncher",
  1422.         Pickup_Weapon,
  1423.         Use_Weapon,
  1424.         Drop_Weapon,
  1425.         Weapon_GrenadeLauncher,
  1426.         "misc/w_pkup.wav",
  1427.         "models/weapons/g_launch/tris.md2", EF_ROTATE,
  1428.         "models/weapons/v_launch/tris.md2",
  1429. /* icon */        "w_glauncher",
  1430. /* pickup */    "Homing Rocket Launcher",
  1431.         0,
  1432.         1,
  1433.         "Rockets",
  1434.         IT_WEAPON|IT_STAY_COOP,
  1435.         WEAP_GRENADELAUNCHER,
  1436.         NULL,
  1437.         0,
  1438. /* precache */ "models/objects/grenade/tris.md2 weapons/grenlf1a.wav weapons/grenlr1b.wav weapons/grenlb1b.wav"
  1439.     },
  1440.  
  1441. /*QUAKED weapon_rocketlauncher (.3 .3 1) (-16 -16 -16) (16 16 16)
  1442. */
  1443.     {
  1444.         "weapon_rocketlauncher",
  1445.         Pickup_Weapon,
  1446.         Use_Weapon,
  1447.         Drop_Weapon,
  1448.         Weapon_RocketLauncher,
  1449.         "misc/w_pkup.wav",
  1450.         "models/weapons/g_rocket/tris.md2", EF_ROTATE,
  1451.         "models/weapons/v_rocket/tris.md2",
  1452. /* icon */        "w_rlauncher",
  1453. /* pickup */    "Rocket Launcher",
  1454.         0,
  1455.         1,
  1456.         "Rockets",
  1457.         IT_WEAPON|IT_STAY_COOP,
  1458.         WEAP_ROCKETLAUNCHER,
  1459.         NULL,
  1460.         0,
  1461. /* precache */ "models/objects/rocket/tris.md2 weapons/rockfly.wav weapons/rocklf1a.wav weapons/rocklr1b.wav models/objects/debris2/tris.md2"
  1462.     },
  1463.  
  1464. /*QUAKED weapon_hyperblaster (.3 .3 1) (-16 -16 -16) (16 16 16)
  1465. */
  1466.     {
  1467.         "weapon_hyperblaster", 
  1468.         Pickup_Weapon,
  1469.         Use_Weapon,
  1470.         Drop_Weapon,
  1471.         Weapon_HyperBlaster,
  1472.         "misc/w_pkup.wav",
  1473.         "models/weapons/g_hyperb/tris.md2", EF_ROTATE,
  1474.         "models/weapons/v_hyperb/tris.md2",
  1475. /* icon */        "w_hyperblaster",
  1476. /* pickup */    "Alien Disruptor",
  1477.         0,
  1478.         1,
  1479.         "Cells",
  1480.         IT_WEAPON|IT_STAY_COOP,
  1481.         WEAP_HYPERBLASTER,
  1482.         NULL,
  1483.         0,
  1484. /* precache */ "weapons/hyprbu1a.wav weapons/hyprbl1a.wav weapons/hyprbf1a.wav weapons/hyprbd1a.wav misc/lasfly.wav"
  1485.     },
  1486.  
  1487. /*QUAKED weapon_railgun (.3 .3 1) (-16 -16 -16) (16 16 16)
  1488. */
  1489.     {
  1490.         "weapon_railgun", 
  1491.         Pickup_Weapon,
  1492.         Use_Weapon,
  1493.         Drop_Weapon,
  1494.         Weapon_Railgun,
  1495.         "misc/w_pkup.wav",
  1496.         "models/weapons/g_rail/tris.md2", EF_ROTATE,
  1497.         "models/weapons/v_rail/tris.md2",
  1498. /* icon */        "w_railgun",
  1499. /* pickup */    "Disruptor",
  1500.         0,
  1501.         1,
  1502.         "Cells",
  1503.         IT_WEAPON|IT_STAY_COOP,
  1504.         WEAP_RAILGUN,
  1505.         NULL,
  1506.         0,
  1507. /* precache */ "weapons/rg_hum.wav"
  1508.     },
  1509.  
  1510. /*QUAKED weapon_bfg (.3 .3 1) (-16 -16 -16) (16 16 16)
  1511. */
  1512.     {
  1513.         "weapon_bfg",
  1514.         Pickup_Weapon,
  1515.         Use_Weapon,
  1516.         Drop_Weapon,
  1517.         Weapon_BFG,
  1518.         "misc/w_pkup.wav",
  1519.         "models/weapons/g_bfg/tris.md2", EF_ROTATE,
  1520.         "models/weapons/v_bfg/tris.md2",
  1521. /* icon */        "w_bfg",
  1522. /* pickup */    "Laser Cannon",
  1523.         0,
  1524.         50,
  1525.         "Cells",
  1526.         IT_WEAPON|IT_STAY_COOP,
  1527.         WEAP_BFG,
  1528.         NULL,
  1529.         0,
  1530. /* precache */ "sprites/s_bfg1.sp2 sprites/s_bfg2.sp2 sprites/s_bfg3.sp2 weapons/bfg__f1y.wav weapons/bfg__l1a.wav weapons/bfg__x1b.wav weapons/bfg_hum.wav"
  1531.     },
  1532.  
  1533.     //
  1534.     // AMMO ITEMS
  1535.     //
  1536. /*QUAKED ammo_shells (.3 .3 1) (-16 -16 -16) (16 16 16)
  1537. */
  1538.     {
  1539.         "ammo_shells",
  1540.         Pickup_Ammo,
  1541.         NULL,
  1542.         Drop_Ammo,
  1543.         NULL,
  1544.         "misc/am_pkup.wav",
  1545.         "models/items/ammo/shells/medium/tris.md2", 0,
  1546.         NULL,
  1547. /* icon */        "a_shells",
  1548. /* pickup */    "Alien Smart Grenade",
  1549. /* width */        3,
  1550.         10,
  1551.         NULL,
  1552.         IT_AMMO,
  1553.         0,
  1554.         NULL,
  1555.         AMMO_SHELLS,
  1556. /* precache */ ""
  1557.     },
  1558. /*QUAKED ammo_shells (.3 .3 1) (-16 -16 -16) (16 16 16)
  1559. */
  1560.     {
  1561.         "ammo_grenades",
  1562.         Pickup_Ammo,
  1563.         NULL,
  1564.         Drop_Ammo,
  1565.         NULL,
  1566.         "misc/am_pkup.wav",
  1567.         "models/items/ammo/grenades/medium/tris.md2", 0,
  1568.         NULL,
  1569. /* icon */        "a_grenades",
  1570. /* pickup */    "Napalm",
  1571. /* width */        3,
  1572.         50,
  1573.         NULL,
  1574.         IT_AMMO,
  1575.         0,
  1576.         NULL,
  1577.         AMMO_GRENADES,
  1578. /* precache */ ""
  1579.     },
  1580.  
  1581. /*QUAKED ammo_bullets (.3 .3 1) (-16 -16 -16) (16 16 16)
  1582. */
  1583.     {
  1584.         "ammo_bullets",
  1585.         Pickup_Ammo,
  1586.         NULL,
  1587.         Drop_Ammo,
  1588.         NULL,
  1589.         "misc/am_pkup.wav",
  1590.         "models/items/ammo/bullets/medium/tris.md2", 0,
  1591.         NULL,
  1592. /* icon */        "a_bullets",
  1593. /* pickup */    "Bullets",
  1594. /* width */        3,
  1595.         50,
  1596.         NULL,
  1597.         IT_AMMO,
  1598.         0,
  1599.         NULL,
  1600.         AMMO_BULLETS,
  1601. /* precache */ ""
  1602.     },
  1603.  
  1604. /*QUAKED ammo_cells (.3 .3 1) (-16 -16 -16) (16 16 16)
  1605. */
  1606.     {
  1607.         "ammo_cells",
  1608.         Pickup_Ammo,
  1609.         NULL,
  1610.         Drop_Ammo,
  1611.         NULL,
  1612.         "misc/am_pkup.wav",
  1613.         "models/items/ammo/cells/medium/tris.md2", 0,
  1614.         NULL,
  1615. /* icon */        "a_cells",
  1616. /* pickup */    "Cells",
  1617. /* width */        3,
  1618.         50,
  1619.         NULL,
  1620.         IT_AMMO,
  1621.         0,
  1622.         NULL,
  1623.         AMMO_CELLS,
  1624. /* precache */ ""
  1625.     },
  1626.  
  1627. /*QUAKED ammo_rockets (.3 .3 1) (-16 -16 -16) (16 16 16)
  1628. */
  1629.     {
  1630.         "ammo_rockets",
  1631.         Pickup_Ammo,
  1632.         NULL,
  1633.         Drop_Ammo,
  1634.         NULL,
  1635.         "misc/am_pkup.wav",
  1636.         "models/items/ammo/rockets/medium/tris.md2", 0,
  1637.         NULL,
  1638. /* icon */        "a_rockets",
  1639. /* pickup */    "Rockets",
  1640. /* width */        3,
  1641.         5,
  1642.         NULL,
  1643.         IT_AMMO,
  1644.         0,
  1645.         NULL,
  1646.         AMMO_ROCKETS,
  1647. /* precache */ ""
  1648.     },
  1649.  
  1650. /*QUAKED ammo_slugs (.3 .3 1) (-16 -16 -16) (16 16 16)
  1651. */
  1652.     {
  1653.         "ammo_slugs",
  1654.         Pickup_Ammo,
  1655.         NULL,
  1656.         Drop_Ammo,
  1657.         NULL,
  1658.         "misc/am_pkup.wav",
  1659.         "models/items/ammo/slugs/medium/tris.md2", 0,
  1660.         NULL,
  1661. /* icon */        "a_slugs",
  1662. /* pickup */    "Slugs",
  1663. /* width */        3,
  1664.         10,
  1665.         NULL,
  1666.         IT_AMMO,
  1667.         0,
  1668.         NULL,
  1669.         AMMO_SLUGS,
  1670. /* precache */ ""
  1671.     },
  1672.  
  1673.  
  1674.     //
  1675.     // POWERUP ITEMS
  1676.     //
  1677. /*QUAKED item_quad (.3 .3 1) (-16 -16 -16) (16 16 16)
  1678. */
  1679.     {
  1680.         "item_quad", 
  1681.         Pickup_Powerup,
  1682.         Use_Quad,
  1683.         Drop_General,
  1684.         NULL,
  1685.         "items/pkup.wav",
  1686.         "models/items/quaddama/tris.md2", EF_ROTATE,
  1687.         NULL,
  1688. /* icon */        "p_quad",
  1689. /* pickup */    "Quad Damage",
  1690. /* width */        2,
  1691.         60,
  1692.         NULL,
  1693.         IT_POWERUP,
  1694.         0,
  1695.         NULL,
  1696.         0,
  1697. /* precache */ "items/damage.wav items/damage2.wav items/damage3.wav"
  1698.     },
  1699.  
  1700. /*QUAKED item_invulnerability (.3 .3 1) (-16 -16 -16) (16 16 16)
  1701. */
  1702.     {
  1703.         "item_invulnerability",
  1704.         Pickup_Powerup,
  1705.         Use_Invulnerability,
  1706.         Drop_General,
  1707.         NULL,
  1708.         "items/pkup.wav",
  1709.         "models/items/invulner/tris.md2", EF_ROTATE,
  1710.         NULL,
  1711. /* icon */        "p_invulnerability",
  1712. /* pickup */    "Invulnerability",
  1713. /* width */        2,
  1714.         300,
  1715.         NULL,
  1716.         IT_POWERUP,
  1717.         0,
  1718.         NULL,
  1719.         0,
  1720. /* precache */ "items/protect.wav items/protect2.wav items/protect4.wav"
  1721.     },
  1722.  
  1723. /*QUAKED item_silencer (.3 .3 1) (-16 -16 -16) (16 16 16)
  1724. */
  1725.     {
  1726.         "item_silencer",
  1727.         Pickup_Powerup,
  1728.         Use_Silencer,
  1729.         Drop_General,
  1730.         NULL,
  1731.         "items/pkup.wav",
  1732.         "models/items/silencer/tris.md2", EF_ROTATE,
  1733.         NULL,
  1734. /* icon */        "p_silencer",
  1735. /* pickup */    "Silencer",
  1736. /* width */        2,
  1737.         60,
  1738.         NULL,
  1739.         IT_POWERUP,
  1740.         0,
  1741.         NULL,
  1742.         0,
  1743. /* precache */ ""
  1744.     },
  1745.  
  1746. /*QUAKED item_breather (.3 .3 1) (-16 -16 -16) (16 16 16)
  1747. */
  1748.     {
  1749.         "item_breather",
  1750.         Pickup_Powerup,
  1751.         Use_Breather,
  1752.         Drop_General,
  1753.         NULL,
  1754.         "items/pkup.wav",
  1755.         "models/items/breather/tris.md2", EF_ROTATE,
  1756.         NULL,
  1757. /* icon */        "p_rebreather",
  1758. /* pickup */    "Rebreather",
  1759. /* width */        2,
  1760.         60,
  1761.         NULL,
  1762.         IT_STAY_COOP|IT_POWERUP,
  1763.         0,
  1764.         NULL,
  1765.         0,
  1766. /* precache */ "items/airout.wav"
  1767.     },
  1768.  
  1769. /*QUAKED item_enviro (.3 .3 1) (-16 -16 -16) (16 16 16)
  1770. */
  1771.     {
  1772.         "item_enviro",
  1773.         Pickup_Powerup,
  1774.         Use_Envirosuit,
  1775.         Drop_General,
  1776.         NULL,
  1777.         "items/pkup.wav",
  1778.         "models/items/enviro/tris.md2", EF_ROTATE,
  1779.         NULL,
  1780. /* icon */        "p_envirosuit",
  1781. /* pickup */    "Environment Suit",
  1782. /* width */        2,
  1783.         60,
  1784.         NULL,
  1785.         IT_STAY_COOP|IT_POWERUP,
  1786.         0,
  1787.         NULL,
  1788.         0,
  1789. /* precache */ "items/airout.wav"
  1790.     },
  1791.  
  1792. /*QUAKED item_ancient_head (.3 .3 1) (-16 -16 -16) (16 16 16)
  1793. Special item that gives +2 to maximum health
  1794. */
  1795.     {
  1796.         "item_ancient_head",
  1797.         Pickup_AncientHead,
  1798.         NULL,
  1799.         NULL,
  1800.         NULL,
  1801.         "items/pkup.wav",
  1802.         "models/items/c_head/tris.md2", EF_ROTATE,
  1803.         NULL,
  1804. /* icon */        "i_fixme",
  1805. /* pickup */    "Ancient Head",
  1806. /* width */        2,
  1807.         60,
  1808.         NULL,
  1809.         0,
  1810.         0,
  1811.         NULL,
  1812.         0,
  1813. /* precache */ ""
  1814.     },
  1815.  
  1816. /*QUAKED item_adrenaline (.3 .3 1) (-16 -16 -16) (16 16 16)
  1817. gives +1 to maximum health
  1818. */
  1819.     {
  1820.         "item_adrenaline",
  1821.         Pickup_Adrenaline,
  1822.         NULL,
  1823.         NULL,
  1824.         NULL,
  1825.         "items/pkup.wav",
  1826.         "models/items/adrenal/tris.md2", EF_ROTATE,
  1827.         NULL,
  1828. /* icon */        "p_adrenaline",
  1829. /* pickup */    "Adrenaline",
  1830. /* width */        2,
  1831.         60,
  1832.         NULL,
  1833.         0,
  1834.         0,
  1835.         NULL,
  1836.         0,
  1837. /* precache */ ""
  1838.     },
  1839.  
  1840. /*QUAKED item_bandolier (.3 .3 1) (-16 -16 -16) (16 16 16)
  1841. */
  1842.     {
  1843.         "item_bandolier",
  1844.         Pickup_Bandolier,
  1845.         NULL,
  1846.         NULL,
  1847.         NULL,
  1848.         "items/pkup.wav",
  1849.         "models/items/band/tris.md2", EF_ROTATE,
  1850.         NULL,
  1851. /* icon */        "p_bandolier",
  1852. /* pickup */    "Bandolier",
  1853. /* width */        2,
  1854.         60,
  1855.         NULL,
  1856.         0,
  1857.         0,
  1858.         NULL,
  1859.         0,
  1860. /* precache */ ""
  1861.     },
  1862.  
  1863. /*QUAKED item_pack (.3 .3 1) (-16 -16 -16) (16 16 16)
  1864. */
  1865.     {
  1866.         "item_pack",
  1867.         Pickup_Pack,
  1868.         NULL,
  1869.         NULL,
  1870.         NULL,
  1871.         "items/pkup.wav",
  1872.         "models/items/pack/tris.md2", EF_ROTATE,
  1873.         NULL,
  1874. /* icon */        "i_pack",
  1875. /* pickup */    "Ammo Pack",
  1876. /* width */        2,
  1877.         180,
  1878.         NULL,
  1879.         0,
  1880.         0,
  1881.         NULL,
  1882.         0,
  1883. /* precache */ ""
  1884.     },
  1885.  
  1886.     //
  1887.     // KEYS
  1888.     //
  1889. /*QUAKED key_data_cd (0 .5 .8) (-16 -16 -16) (16 16 16)
  1890. key for computer centers
  1891. */
  1892.     {
  1893.         "key_data_cd",
  1894.         Pickup_Key,
  1895.         NULL,
  1896.         Drop_General,
  1897.         NULL,
  1898.         "items/pkup.wav",
  1899.         "models/items/keys/data_cd/tris.md2", EF_ROTATE,
  1900.         NULL,
  1901.         "k_datacd",
  1902.         "Data CD",
  1903.         2,
  1904.         0,
  1905.         NULL,
  1906.         IT_STAY_COOP|IT_KEY,
  1907.         0,
  1908.         NULL,
  1909.         0,
  1910. /* precache */ ""
  1911.     },
  1912.  
  1913. /*QUAKED key_power_cube (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN NO_TOUCH
  1914. warehouse circuits
  1915. */
  1916.     {
  1917.         "key_power_cube",
  1918.         Pickup_Key,
  1919.         NULL,
  1920.         Drop_General,
  1921.         NULL,
  1922.         "items/pkup.wav",
  1923.         "models/items/keys/power/tris.md2", EF_ROTATE,
  1924.         NULL,
  1925.         "k_powercube",
  1926.         "Power Cube",
  1927.         2,
  1928.         0,
  1929.         NULL,
  1930.         IT_STAY_COOP|IT_KEY,
  1931.         0,
  1932.         NULL,
  1933.         0,
  1934. /* precache */ ""
  1935.     },
  1936.  
  1937. /*QUAKED key_pyramid (0 .5 .8) (-16 -16 -16) (16 16 16)
  1938. key for the entrance of jail3
  1939. */
  1940.     {
  1941.         "key_pyramid",
  1942.         Pickup_Key,
  1943.         NULL,
  1944.         Drop_General,
  1945.         NULL,
  1946.         "items/pkup.wav",
  1947.         "models/items/keys/pyramid/tris.md2", EF_ROTATE,
  1948.         NULL,
  1949.         "k_pyramid",
  1950.         "Pyramid Key",
  1951.         2,
  1952.         0,
  1953.         NULL,
  1954.         IT_STAY_COOP|IT_KEY,
  1955.         0,
  1956.         NULL,
  1957.         0,
  1958. /* precache */ ""
  1959.     },
  1960.  
  1961. /*QUAKED key_data_spinner (0 .5 .8) (-16 -16 -16) (16 16 16)
  1962. key for the city computer
  1963. */
  1964.     {
  1965.         "key_data_spinner",
  1966.         Pickup_Key,
  1967.         NULL,
  1968.         Drop_General,
  1969.         NULL,
  1970.         "items/pkup.wav",
  1971.         "models/items/keys/spinner/tris.md2", EF_ROTATE,
  1972.         NULL,
  1973.         "k_dataspin",
  1974.         "Data Spinner",
  1975.         2,
  1976.         0,
  1977.         NULL,
  1978.         IT_STAY_COOP|IT_KEY,
  1979.         0,
  1980.         NULL,
  1981.         0,
  1982. /* precache */ ""
  1983.     },
  1984.  
  1985. /*QUAKED key_pass (0 .5 .8) (-16 -16 -16) (16 16 16)
  1986. security pass for the security level
  1987. */
  1988.     {
  1989.         "key_pass",
  1990.         Pickup_Key,
  1991.         NULL,
  1992.         Drop_General,
  1993.         NULL,
  1994.         "items/pkup.wav",
  1995.         "models/items/keys/pass/tris.md2", EF_ROTATE,
  1996.         NULL,
  1997.         "k_security",
  1998.         "Security Pass",
  1999.         2,
  2000.         0,
  2001.         NULL,
  2002.         IT_STAY_COOP|IT_KEY,
  2003.         0,
  2004.         NULL,
  2005.         0,
  2006. /* precache */ ""
  2007.     },
  2008.  
  2009. /*QUAKED key_blue_key (0 .5 .8) (-16 -16 -16) (16 16 16)
  2010. normal door key - blue
  2011. */
  2012.     {
  2013.         "key_blue_key",
  2014.         Pickup_Key,
  2015.         NULL,
  2016.         Drop_General,
  2017.         NULL,
  2018.         "items/pkup.wav",
  2019.         "models/items/keys/key/tris.md2", EF_ROTATE,
  2020.         NULL,
  2021.         "k_bluekey",
  2022.         "Blue Key",
  2023.         2,
  2024.         0,
  2025.         NULL,
  2026.         IT_STAY_COOP|IT_KEY,
  2027.         0,
  2028.         NULL,
  2029.         0,
  2030. /* precache */ ""
  2031.     },
  2032.  
  2033. /*QUAKED key_red_key (0 .5 .8) (-16 -16 -16) (16 16 16)
  2034. normal door key - red
  2035. */
  2036.     {
  2037.         "key_red_key",
  2038.         Pickup_Key,
  2039.         NULL,
  2040.         Drop_General,
  2041.         NULL,
  2042.         "items/pkup.wav",
  2043.         "models/items/keys/red_key/tris.md2", EF_ROTATE,
  2044.         NULL,
  2045.         "k_redkey",
  2046.         "Red Key",
  2047.         2,
  2048.         0,
  2049.         NULL,
  2050.         IT_STAY_COOP|IT_KEY,
  2051.         0,
  2052.         NULL,
  2053.         0,
  2054. /* precache */ ""
  2055.     },
  2056.  
  2057. /*QUAKED key_commander_head (0 .5 .8) (-16 -16 -16) (16 16 16)
  2058. tank commander's head
  2059. */
  2060.     {
  2061.         "key_commander_head",
  2062.         Pickup_Key,
  2063.         NULL,
  2064.         Drop_General,
  2065.         NULL,
  2066.         "items/pkup.wav",
  2067.         "models/monsters/commandr/head/tris.md2", EF_GIB,
  2068.         NULL,
  2069. /* icon */        "k_comhead",
  2070. /* pickup */    "Commander's Head",
  2071. /* width */        2,
  2072.         0,
  2073.         NULL,
  2074.         IT_STAY_COOP|IT_KEY,
  2075.         0,
  2076.         NULL,
  2077.         0,
  2078. /* precache */ ""
  2079.     },
  2080.  
  2081. /*QUAKED key_airstrike_target (0 .5 .8) (-16 -16 -16) (16 16 16)
  2082. tank commander's head
  2083. */
  2084.     {
  2085.         "key_airstrike_target",
  2086.         Pickup_Key,
  2087.         NULL,
  2088.         Drop_General,
  2089.         NULL,
  2090.         "items/pkup.wav",
  2091.         "models/items/keys/target/tris.md2", EF_ROTATE,
  2092.         NULL,
  2093. /* icon */        "i_airstrike",
  2094. /* pickup */    "Airstrike Marker",
  2095. /* width */        2,
  2096.         0,
  2097.         NULL,
  2098.         IT_STAY_COOP|IT_KEY,
  2099.         0,
  2100.         NULL,
  2101.         0,
  2102. /* precache */ ""
  2103.     },
  2104.  
  2105.     {
  2106.         NULL,
  2107.         Pickup_Health,
  2108.         NULL,
  2109.         NULL,
  2110.         NULL,
  2111.         "items/pkup.wav",
  2112.         NULL, 0,
  2113.         NULL,
  2114. /* icon */        "i_health",
  2115. /* pickup */    "Health",
  2116. /* width */        3,
  2117.         0,
  2118.         NULL,
  2119.         0,
  2120.         0,
  2121.         NULL,
  2122.         0,
  2123. /* precache */ "items/s_health.wav items/n_health.wav items/l_health.wav items/m_health.wav"
  2124.     },
  2125.  
  2126.     // end of list marker
  2127.     {NULL}
  2128. };
  2129.  
  2130.  
  2131. /*QUAKED item_health (.3 .3 1) (-16 -16 -16) (16 16 16)
  2132. */
  2133. void SP_item_health (edict_t *self)
  2134. {
  2135.     if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) )
  2136.     {
  2137.         G_FreeEdict (self);
  2138.         return;
  2139.     }
  2140.     if(self->spawnflags & 1)
  2141.         self->model = "models/items/healing/alien/tris.md2";
  2142.     else
  2143.         self->model = "models/items/healing/medium/tris.md2";
  2144.     self->count = 10;
  2145.     SpawnItem (self, FindItem ("Health"));
  2146.     gi.soundindex ("items/n_health.wav");
  2147. }
  2148.  
  2149. /*QUAKED item_health_small (.3 .3 1) (-16 -16 -16) (16 16 16)
  2150. */
  2151. void SP_item_health_small (edict_t *self)
  2152. {
  2153.     if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) )
  2154.     {
  2155.         G_FreeEdict (self);
  2156.         return;
  2157.     }
  2158.     
  2159.     self->model = "models/items/healing/stimpack/tris.md2";
  2160.     self->count = 2;
  2161.     SpawnItem (self, FindItem ("Health"));
  2162.     self->style = HEALTH_IGNORE_MAX;
  2163.     gi.soundindex ("items/s_health.wav");
  2164. }
  2165.  
  2166. /*QUAKED item_health_large (.3 .3 1) (-16 -16 -16) (16 16 16)
  2167. */
  2168. void SP_item_health_large (edict_t *self)
  2169. {
  2170.     if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) )
  2171.     {
  2172.         G_FreeEdict (self);
  2173.         return;
  2174.     }
  2175.  
  2176.     if(self->spawnflags & 1)
  2177.         self->model = "models/items/healing/alien/tris.md2";
  2178.     else
  2179.         self->model = "models/items/healing/medium/tris.md2";
  2180.     self->model = "models/items/healing/large/tris.md2";
  2181.     self->count = 25;
  2182.     SpawnItem (self, FindItem ("Health"));
  2183.     gi.soundindex ("items/l_health.wav");
  2184. }
  2185.  
  2186. /*QUAKED item_health_mega (.3 .3 1) (-16 -16 -16) (16 16 16)
  2187. */
  2188. void SP_item_health_mega (edict_t *self)
  2189. {
  2190.     if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) )
  2191.     {
  2192.         G_FreeEdict (self);
  2193.         return;
  2194.     }
  2195.  
  2196.     self->model = "models/items/mega_h/tris.md2";
  2197.     self->count = 100;
  2198.     SpawnItem (self, FindItem ("Health"));
  2199.     gi.soundindex ("items/m_health.wav");
  2200.     self->style = HEALTH_IGNORE_MAX|HEALTH_TIMED;
  2201. }
  2202.  
  2203.  
  2204. void InitItems (void)
  2205. {
  2206.     game.num_items = sizeof(itemlist)/sizeof(itemlist[0]) - 1;
  2207. }
  2208.  
  2209.  
  2210.  
  2211. /*
  2212. ===============
  2213. SetItemNames
  2214.  
  2215. Called by worldspawn
  2216. ===============
  2217. */
  2218. void SetItemNames (void)
  2219. {
  2220.     int        i;
  2221.     gitem_t    *it;
  2222.  
  2223.     for (i=0 ; i<game.num_items ; i++)
  2224.     {
  2225.         it = &itemlist[i];
  2226.         gi.configstring (CS_ITEMS+i, it->pickup_name);
  2227.     }
  2228.  
  2229.     jacket_armor_index = ITEM_INDEX(FindItem("Jacket Armor"));
  2230.     combat_armor_index = ITEM_INDEX(FindItem("Combat Armor"));
  2231.     body_armor_index   = ITEM_INDEX(FindItem("Body Armor"));
  2232.     power_screen_index = ITEM_INDEX(FindItem("Power Screen"));
  2233.     power_shield_index = ITEM_INDEX(FindItem("Power Shield"));
  2234. }
  2235.